const $ = (s) => document.querySelector(s);

function output(data, selector = ".output") {
  $(selector).textContent = data;
}

function clearOutput(selector = '.output') {
  $(selector).innerHTML = ''
}

function outputChunk(str, selector = '.output') {
  const jsonRe = /^[\{\[].*[\}\]]$/
  if (jsonRe.test(str)) {
    const data = JSON.parse(str)
    if (data.error) {
      alert(data.msg)
      return
    }
  }
  const container = $(selector)
  const div = document.createElement('div')
  if (str.trim().match(/^Done in/i)) {
    str = `<div class=result-tips>${str}</div>`
  }
  if (str.trim().match(/\[INFO\]/)) {
    div.className = 'info-line'
  }
  if (str.trim().match(/\[LOG\]/)) {
    div.className = 'log-line'
  }
  if (str.trim().match(/building start/)) {
    div.className = 'hide'
  }
  
  div.innerHTML = str.replace(/\n|\r|\n\r/g, '<br/>')
  // div.textContent = str
  container.appendChild(div)
  return container
}

const querystring = {
  stringify(params) {
    return Object.keys(params)
      .reduce(
        (qstr, key) => qstr + `&${key}=${encodeURIComponent(params[key])}`,
        ""
      )
      .replace(/^&/, "");
  },
  parse(qstr) {
    if (!qstr) return {}
    return qstr.replace(/^\?/, '').split("&").reduce((params, part) => {
      const [key, val] = part.split("=");
      const value = decodeURIComponent(val);
      params[key] = value;
      return params;
    }, {});
  },
};

function capitalize(str = '') {
  if (!str) return ''
  return str[0].toUpperCase() + str.slice(1).toLowerCase()
}

function getQuery(url) {
  url = url || location.href
  url = url.replace(/#.*$/, '')
  const isUrl = /^(https?:)?\/\//.test(url)
  const search = isUrl ? url.split('?')[1] || '' : url
  return querystring.parse(search)
}

function isEmpty(val) {
  if (typeof val === "string") {
    return val === "";
  } else if (Array.isArray(val)) {
    return val.length === 0;
  } else if (Object.prototype.toString.call(val).slice(8, -1) === "Object") {
    return Object.keys(val).length === 0;
  }
  return false;
}

const request = (function () {
  const get = (url, params = {}) => {
    const uri = isEmpty(params)
      ? url
      : url + (url.includes("?") ? "&" : "?") + querystring.stringify(params);

    return new Promise((resolve) => {
      const dataPromise = fetch(uri, { method: "GET" })
        .then((res) => res.text())
        .then((data) => data);
      resolve(dataPromise);
    });
  };

  const post = (url, data = {}) => {
    return new Promise((resolve) => {
      const dataPromise = fetch(url, {
        body: querystring.stringify(data),
        method: "POST",
        headers: {
          'Content-Type': 'application/x-www-urlencoded'
        }
      })
        .then((res) => res.text())
        .then((data) => data);

      resolve(dataPromise);
    });
  };

  return { get, post };
})();

const SRequest = (function () {
  const get = async (url, params = {}, dataCb = console.log) => {
    const uri = isEmpty(params)
      ? url
      : url + (url.includes("?") ? "&" : "?") + querystring.stringify(params);

      const response = await fetch(uri, { method: "GET" , headers: {
        'Content-Type': 'application/x-www-urlencoded'
      }})
      const reader = response.body.getReader()
      console.log('content-type', response.headers.get('content-type'))

      while(true) {
        const { done, value} = await reader.read()

        const decoder = new TextDecoder()
        if (done) {
          break;
        }
        dataCb(decoder.decode(value))
      }

      return response
  };

  const post = async (url, data = {}, dataCb = console.log, doneCb = console.log) => {
      const response = await fetch(url, {
        body: querystring.stringify(data),
        // body: JSON.stringify(data),
        method: "POST",
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
          // 'Content-Type': 'application/json'
        }
      })
      const reader = response.body.getReader()
      console.log('content-type', response.headers.get('content-type'))
      while(true) {
        const { done, value } = await reader.read()
        if (done) {
          doneCb()
          break;
        }

        const decoder = new TextDecoder()
        dataCb(decoder.decode(value))
      }

      return response
  };

  return { get, post };
})();

function hide(selector) {
  const ele = typeof selector === 'string' ? $(selector) : selector
  ele.style.visibility = 'hidden'
}
function show(selector) {
  const ele = typeof selector === 'string' ? $(selector) : selector
  ele.style.visibility = 'visible'
}

function sleep(second = 1) {
  return new Promise(resolve => setTimeout(resolve, second * 1000))
}

function autoScroll(delay = 1) {
  let timer = ''
  const doScroll = () => {
    window.scrollBy(0, 800)
    timer = setTimeout(doScroll, delay * 1000)
  }

  doScroll()

  const stop = () => { clearTimeout(timer) }
  autoScroll.stop = stop

  return stop
}


function dateFormat(date = 'now', isCN = true) {
  if (date === 'now') {
    date = new Date()
  }

  if (typeof date === 'string') {
    date = new Date(date)
  }

  if (!date instanceof Date) {
    console.log('date invalid')
    return null
  }


  const [year, month, day] = [date.getFullYear(), date.getMonth() + 1, date.getDate()]
  return isCN ? `${year}年${month}月${day}日` : [year, month, day].join('-')
}

